package top.wilsonlv.jaguar.openfeign.component;

import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.cloud.openfeign.FeignClientFactoryBean;
import org.springframework.stereotype.Component;

/**
 * @author lvws
 * @since 2022/1/6
 */
@Component
@RequiredArgsConstructor
public class FeignClientRegister {

    private final DefaultListableBeanFactory beanFactory;

    public <T> void registerFeignClient(String beanName, Class<T> clazz, String serverName, String contextId) {
        FeignClientFactoryBean factoryBean = new FeignClientFactoryBean();
        factoryBean.setBeanFactory(beanFactory);
        factoryBean.setName(serverName);
        factoryBean.setContextId(contextId);
        factoryBean.setType(clazz);
        factoryBean.setDecode404(false);
        factoryBean.setPath("");
        factoryBean.setUrl("");

        @SuppressWarnings("unchecked")
        BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(clazz, () -> (T) factoryBean.getObject());
        definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
        definition.setLazyInit(false);

        AbstractBeanDefinition beanDefinition = definition.getBeanDefinition();
        beanDefinition.setAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE, clazz.getName());
        beanDefinition.setAttribute("feignClientsRegistrarFactoryBean", factoryBean);
        beanDefinition.setPrimary(false);

        beanFactory.registerBeanDefinition(beanName, beanDefinition);
    }


}
